#pragma once

#include <functional>

#include "utils/likely.h"
#include "aio/ctx.h"


namespace pg {

using namespace std;

struct Fsm;

struct FsmEvent {
    Fsm* fsm{};

    int src{-1};
    void* srcptr{nullptr};
    int type{-1};

    void process() {
    }
};

struct FsmOwner {
    int src;
    Fsm* fsm;
};

struct Fsm {
    using FsmFn = function<void (Fsm* fsm, int src, int type, void* srcptr)>;
    FsmFn fn;
    FsmFn shutdown_fn;

    enum FsmState {IDLE, ACTIVE, STOPPING};
    FsmState state{IDLE};
    int src{-1};
    void* srcptr{nullptr};

    Fsm* owner{nullptr};

    Ctx* ctx;

    void feed(int src, int type, void* srcptr) {
        if (unlikely(state != STOPPING))
            fn(this, src, type, srcptr);
        else
            shutdown_fn(this, src, type, srcptr);
    }
};

}
